package com.im.web.service;

import com.im.common.toolkit.BeanUtils;
import com.im.common.toolkit.CommonUtils;
import com.im.web.core.QueryUtils;
import com.im.web.core.model.Relation;
import com.im.web.core.model.UserChat;
import com.im.web.core.model.UserInfo;
import com.im.web.core.repository.UserInfoRepository;
import com.im.web.core.service.BaseService;
import com.im.web.response.ResultMsg;
import com.im.web.response.UserRelation;
import com.im.web.response.UserRelationInfo;
import com.im.web.session.UserInfoSession;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.OrderSpecifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import static com.im.common.Constants.IS_EXIST;
import static com.im.web.core.model.QRelation.relation;
import static com.im.web.core.model.QUserChat.userChat;

/**
 * @author gongym
 * @date 2019/1/16 11:30
 */
@Service
public class UserService extends BaseService {
  private final com.im.web.session.UserInfoSession userInfoSession;
  private final UserInfoRepository userInfoRepository;

  @Autowired
  public UserService(UserInfoSession userInfoSession, UserInfoRepository userInfoRepository) {
    this.userInfoSession = userInfoSession;
    this.userInfoRepository = userInfoRepository;
  }

  /**
   * @description: 根据请求头中的信息获取当前登录的用户（应该用此API获取用户信息）
   * @return 格式化JSON
   * @author gongym
   * @date 2019/2/15 11:17
   */
  public String userInfo() {
    return ResultMsg.success(userInfoSession.getCurrentUser());
  }

  /**
   * @description: 根据用户ID获取用户信息（此API慎用）
   * @param userId 用户ID
   * @return 格式化JSON
   * @author gongym
   * @date 2019/2/15 11:17
   */
  public String userInfo(Long userId) {
    Optional<UserInfo> userInfoOptional = userInfoRepository.findById(userId);
    UserInfo userInfo = userInfoOptional.orElse(null);
    if (null != userInfo) {
      return ResultMsg.success(userInfo);
    } else {
      return ResultMsg.fail("获取用户信息失败");
    }
  }

  /**
   * @description: 获取用户聊天列表
   * @param userId 用户ID
   * @return 格式化JSON
   * @author gongym
   * @date 2019/2/15 11:15
   */
  @SuppressWarnings("Duplicates")
  public String getUserChat(Long userId) {
    QueryUtils queryUtils = new QueryUtils();
    queryUtils
        .putExpression(userChat.userId.eq(userId))
        .putExpression(userChat.delFlag.eq(IS_EXIST));
    OrderSpecifier<Date> editTimeDesc = userChat.editTime.desc();
    QueryResults<UserChat> userChatQueryResults =
        queryFactory
            .selectFrom(userChat)
            .where(queryUtils.buildQuery())
            .orderBy(editTimeDesc)
            .fetchResults();
    return ResultMsg.success(userChatQueryResults.getResults());
  }

  /**
   * @description: 获取用户的联系人列表
   * @param userId 用户ID
   * @return 格式化JSON
   * @author gongym
   * @date 2019/2/15 11:09
   */
  @SuppressWarnings("Duplicates")
  public String getUserRelation(Long userId) {
    QueryUtils queryUtils = new QueryUtils();
    queryUtils
        .putExpression(relation.userId.eq(userId))
        .putExpression(relation.delFlag.eq(IS_EXIST));
    QueryResults<Relation> userRelationQueryResults =
        queryFactory.selectFrom(relation).where(queryUtils.buildQuery()).fetchResults();
    List<Relation> relationList = userRelationQueryResults.getResults();
    List<UserRelation> userRelationList = new ArrayList<>();
    relationList.forEach(
        relation -> {
          Long friendId = relation.getFriendId();
          String friendNickname = relation.getFriendNickname();
          String groupName = relation.getGroupName();
          if (CommonUtils.isEmpty(userRelationList)) {
            UserRelation userRelation = new UserRelation();
            userRelation.setUserRelationName(groupName);
            userRelation.setUserRelationList(
                new ArrayList<UserRelationInfo>() {
                  private static final long serialVersionUID = -8518054533372101177L;

                  {
                    UserRelationInfo userRelationInfo = new UserRelationInfo();
                    userRelationInfo.setUserId(friendId);
                    userRelationInfo.setNickname(friendNickname);
                    add(userRelationInfo);
                  }
                });
            userRelationList.add(userRelation);
          } else {
            boolean isExist = false;
            for (UserRelation userRelation : userRelationList) {
              String userRelationType = userRelation.getUserRelationName();
              if (groupName.equals(userRelationType)) {
                UserRelationInfo userRelationInfo = new UserRelationInfo();
                userRelationInfo.setUserId(friendId);
                userRelationInfo.setNickname(friendNickname);
                userRelation.getUserRelationList().add(userRelationInfo);
                isExist = true;
              }
            }
            if (!isExist) {
              UserRelation userRelation = new UserRelation();
              userRelation.setUserRelationName(groupName);
              userRelation.setUserRelationList(
                  new ArrayList<UserRelationInfo>() {
                    private static final long serialVersionUID = -6344057150880285255L;

                    {
                      UserRelationInfo userRelationInfo = new UserRelationInfo();
                      userRelationInfo.setUserId(friendId);
                      userRelationInfo.setNickname(friendNickname);
                      add(userRelationInfo);
                    }
                  });
              userRelationList.add(userRelation);
            }
          }
        });
    return ResultMsg.success(userRelationList);
  }

  /**
   * @description: 用户获取自己联系人的简要信息（慎用，需要做深度判断，需要在客户端缓存）
   * @param userId 用户ID
   * @return 格式化JSON
   * @author gongym
   * @date 2019/2/15 11:23
   */
  public String getUserRelationInfo(Long userId) {
    Optional<UserInfo> userInfoOptional = userInfoRepository.findById(userId);
    UserInfo userInfo = userInfoOptional.orElse(null);
    if (null != userInfo) {
      UserRelationInfo userRelationInfo = new UserRelationInfo();
      BeanUtils.copy(userInfo, userRelationInfo);
      return ResultMsg.success(userRelationInfo);
    } else {
      return ResultMsg.fail("获取用户信息失败");
    }
  }
}
